package avicit.bdp.dms.perm.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.common.utils.CheckParaUtils;
import avicit.bdp.dms.perm.dao.DataSecretDao;
import avicit.bdp.dms.perm.dto.DataSecretDTO;
import avicit.bdp.dms.perm.utils.common.PermCommonService;
import avicit.platform6.api.sysuser.dto.SysUser;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.context.ThreadContextHelper;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.github.pagehelper.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间：2021-03-25
 * @类说明：DataSecretService
 * @修改记录：
 * @注意事项：
 * @主要功能：密级管理服务
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DataSecretService extends BaseService<DataSecretDao, DataSecretDTO> {
  private static final Logger logger = LoggerFactory.getLogger(DataSecretService.class);

  @Autowired private DataSecretDao dataSecretDao;

  /** 数据权限-用户映射关系服务对象 */
  @Autowired private PermCommonService commService;

  /**
   * 启用密级管理功能时，设置需要拦截的用户列表
   *
   * @param dataSecretDto
   */
  public void addDataSecret(DataSecretDTO dataSecretDto) {
    // step1:合法性检查
    CheckParaUtils.checkObjectValidity(dataSecretDto, logger, "入参为null，启用密级功能失败.");
    CheckParaUtils.checkStringValidity(dataSecretDto.getUserIdList(), logger, "未设置用户列表，启用密级功能失败.");

    // step2:元数据持久化
    saveDataSecret2Db(dataSecretDto);
  }

  /**
   * 停用密级管理功能时，删除设置的用户列表
   *
   * @param dataSecretDto
   * @return
   */
  public void removeDataSecret(DataSecretDTO dataSecretDto) {
    // step1:合法性检查
    CheckParaUtils.checkObjectValidity(dataSecretDto, logger, "入参为null，启用密级功能失败.");
    CheckParaUtils.checkStringValidity(dataSecretDto.getId(), logger, "未设置用户列表，启用密级功能失败.");

    // step2:停用密级管理功能
    removeSingleDataSecret(dataSecretDto.getId());
  }

  /**
   * 修改密级管理需要拦截的用户列表
   *
   * @param dataSecretDto
   * @return
   */
  public void updateDataSecret(DataSecretDTO dataSecretDto) {
    // step1:合法性检查
    CheckParaUtils.checkObjectValidity(dataSecretDto, logger, "入参为null，启用密级功能失败.");
    CheckParaUtils.checkStringValidity(dataSecretDto.getId(), logger, "未设置用户列表，启用密级功能失败.");
    DataSecretDTO currDataSecretDto = queryDataSecret(dataSecretDto.getId());

    // step2:更新DB
    updateDataSecretInner(dataSecretDto, currDataSecretDto);
  }

  /**
   * 列举当前密级管理需要拦截的用户列表
   *
   * @return
   */
  public QueryRespBean<DataSecretDTO> listDataSecrets() {
    QueryRespBean<DataSecretDTO> queryRespBean = new QueryRespBean<>();

    // step1:查表，默认表中只有一个或零个数据
    Page<DataSecretDTO> dataSecretDtoList = dataSecretDao.getDataSecretList(null);
    queryRespBean.setResult(dataSecretDtoList);

    // step2:设置中文用户名
    List<DataSecretDTO> tmpDataSecretDtoList = dataSecretDtoList.getResult();
    for (DataSecretDTO dto : tmpDataSecretDtoList) {
      dto.setCnUserIdList(this.commService.getUserNameByIds(dto.getUserIdList()));
    }

    return queryRespBean;
  }

  /**
   * 对外接口；根据当前登录用户，获取密级过滤cond
   *
   * @return 返回当前用户对应的密级范围
   */
  public String getDataSecretCond() {
    if (!isReleasedDataSecret()) {
      return null;
    }

    return getUserSecretLevel();
  }

  /**
   * 密级管理信息持久化到DB
   *
   * @param dataSecretDto
   */
  private void saveDataSecret2Db(DataSecretDTO dataSecretDto) {
    // step1:持久化
    dataSecretDto.setId(ComUtil.getId());
    insert(dataSecretDto);

    // step2:记录平台日志
    BdpLogUtil.log4Insert(dataSecretDto);
  }

  /**
   * 停用密级管理功能，移除密级拦截用户列表
   *
   * @param id
   */
  private void removeSingleDataSecret(String id) {
    // step1:根据ID获取密级管理信息
    DataSecretDTO queryRet = queryDataSecret(id);

    // step2:移除密级管理信息
    deleteByPrimaryKey(id);

    // step3:记录平台日志
    BdpLogUtil.log4Delete(queryRet);
  }

  /**
   * 根据ID获取密级拦截用户列表
   *
   * @param id
   * @return
   */
  private DataSecretDTO queryDataSecret(String id) {
    CheckParaUtils.checkStringValidity(id, logger, "主键ID为null，查询密级管理功能失败.");

    DataSecretDTO queryRet = selectByPrimaryKey(id);
    CheckParaUtils.checkObjectValidity(queryRet, logger, String.format("查询密级拦截用户列表失败，id=%S", id));

    return queryRet;
  }

  /**
   * 更新密级拦截用户列表
   *
   * @param newDataSecretDto
   * @param oldDataSecretDto
   */
  private void updateDataSecretInner(
      DataSecretDTO newDataSecretDto, DataSecretDTO oldDataSecretDto) {
    // step1:更新DB
    updateByPrimaryKeySelective(newDataSecretDto);

    // step2:记录平台日志
    BdpLogUtil.log4Update(newDataSecretDto, oldDataSecretDto);
  }

  /**
   * 判断是否需要密级拦截
   *
   * @return true：需要拦截，false：不需要拦截
   */
  private boolean isReleasedDataSecret() {
    Page<DataSecretDTO> queryRet = dataSecretDao.getDataSecretList(ThreadContextHelper.getUserId());
    List<DataSecretDTO> dataSecretDtos = queryRet.getResult();
    return dataSecretDtos.size() > 0;
  }

  /**
   * 获取用户对应的密级范围
   *
   * @return
   */
  private String getUserSecretLevel() {
    // step1:获取用户自身密级
    SysUser sysUser = this.commService.getSysUserInfoById(ThreadContextHelper.getUserId());
    if (sysUser == null) {
      return null;
    }

    // step2:根据用户密级，调用V6平台接口获取对应的文档密级
    List<String> secretWordList = this.commService.getSecretWordList(sysUser.getSecretLevel());
    if (CollectionUtils.isNotEmpty(secretWordList)) {
      if (secretWordList.size() == 1) {
        return secretWordList.get(0);
      }

      return String.join(",", secretWordList);
    }

    return null;
  }
}
